/**
 * K线图
 * @author zxy
 * @date  2021-03-15
 */
import React from 'react';
import PropTypes, { element } from 'prop-types';
import ReactEcharts from 'echarts-for-react';
import { Spin } from 'antd';
import { NoDataC } from '@/src/components/other';
import Color from '../../../css/colors';
import _ from 'lodash';

class CandlestickChartsC extends React.Component {
  // 入参默认值设置
  static defaultProps = {
    data: undefined, // 默认无数据,markPoint的标注为data内的trading字段 eg：{ type: '买', value: 2360 }
    // markPoint: [], // 默认无markPoint
    height: '100%', // 图形高度默认为父节点的100%
    width: '100%', // 图形宽度默认为父节点的100%
    toolTipFormat: undefined, // 默认按自定义的提示信息样式展示
    gridLeft: 60, // 默认左轴距离左侧距离为60
    gridRight: 60, // 默认右轴距离右侧距离为60
    maxBarNumber: 30, // 默认展示30条数据，超过用滚动条
  };

  shouldComponentUpdate(nextProps) {
    const props = this.props ? JSON.stringify(this.props) : '';
    const propsN = nextProps ? JSON.stringify(nextProps) : '';
    if (props === propsN) {
      return false;
    } else {
      return true;
    }
  }

  // 返回option
  getOption = () => {
    const { gridLeft, gridRight, toolTipFormat, maxBarNumber } = this.props;
    const { xAxisData, seriesData, markPointData, max, min } = this.splitData(this.props.data);
    const displayRoom = this.props.data.length > maxBarNumber; // 设置当数据不足30个时,不展示zoom

    return {
      // 鼠标移动上去提示信息
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross', // tooltip展示十字型
          crossStyle: {
            color: Color.echartItems.tooltipCross,
          },
          label: {
            backgroundColor: Color.echartItems.tooltipBg,
            color: Color.echartItems.toolLable,
            padding: [7, 7, 5, 7],
            show: true,
          },
        },
        formatter: toolTipFormat
          ? toolTipFormat
          : (params) => {
              const markPoint = this.props.data.filter((item) => item.time === params[0].name);
              let markPointStr = '';
              if (markPoint && markPoint.length == 1 && markPoint[0].trading) {
                // 买
                const buy = markPoint[0].trading.filter((item) => item.type == '买');
                if (buy && buy.length > 0) {
                  const buyArr = [];
                  let buyStr = '';
                  buy.forEach((element, index) => {
                    if (index != 0) {
                      buyStr += '，';
                    }
                    if (index != 0 && index % 10 == 0) {
                      buyArr.push(buyStr);
                      buyStr = '';
                    }
                    buyStr += element.value;
                  });
                  buyArr.push(buyStr);
                  markPointStr += `<div>&nbsp;&nbsp;--买：`;
                  buyArr.forEach((item, index) => {
                    if (index == 0) {
                      markPointStr += `${item}</div>`;
                    } else {
                      markPointStr += `<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${item}</div>`;
                    }
                  });
                }

                // 卖
                const sale = markPoint[0].trading.filter((item) => item.type == '卖');
                if (sale && sale.length > 0) {
                  const saleArr = [];
                  let saleStr = '';
                  sale.forEach((element, index) => {
                    if (index != 0) {
                      saleStr += '，';
                    }
                    if (index != 0 && index % 10 == 0) {
                      saleArr.push(saleStr);
                      saleStr = '';
                    }
                    saleStr += element.value;
                  });
                  saleArr.push(saleStr);
                  markPointStr += `<div>&nbsp;&nbsp;--卖：`;
                  saleArr.forEach((item, index) => {
                    if (index == 0) {
                      markPointStr += `${item}</div>`;
                    } else {
                      markPointStr += `<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${item}</div>`;
                    }
                  });
                }
              }
              let str = `<div style="color:${Color.echartItems.tooltipLabel}">`;
              str += `<div>${params[0].name}</div>`;

              params.map((item) => {
                const value = item.data;
                str += `<div>
                                <div style="display:flex;align-items:center;font-weight:800; ">
                                    <div style="border:1px solid ${Color.echartItems.toolLable};width:10px;height:10px;border-radius:50%;background-color:${item.color};margin-right:10px"></div>
                                        K线说明：
                                </div>
                                <div>
                                    &nbsp;&nbsp;--开盘价： ${value[1]}
                                </div>
                                <div>
                                    &nbsp;&nbsp;--收盘价： ${value[2]}
                                </div>
                                <div>
                                    &nbsp;&nbsp;--最低价： ${value[3]}
                                </div>
                                <div>
                                    &nbsp;&nbsp;--最高价： ${value[4]}
                                </div>`;
                if (markPointStr != '') {
                  str += `
                                <div style='height:15px;'></div>
                                <div style="display:flex;align-items:center;font-weight:800;">
                                    <div style="border:1px solid ${Color.echartItems.toolLable};width:10px;height:10px;border-radius:50%;background-color:${item.color};margin-right:10px"></div>
                                        买卖点说明：
                                </div>
                                ${markPointStr}`;
                }
                str += '</div>';
              });

              str += '</div>';
              return str;
            },
        padding: [10, 15, 10, 15],
        confine: true, // 是否将 tooltip 框限制在图表的区域内
      },
      backgroundColor: Color.echartItems.bgColor, // echarts整个画布的背景色
      // 图例
      legend: {
        show: false,
      },
      // 直角坐标系内绘图网格
      grid: {
        left: gridLeft,
        right: gridRight,
        top: 50,
        bottom: 100,
      },
      // 横轴
      xAxis: {
        type: 'category',
        boundaryGap: true, // 标记横轴左右是否有空隙
        data: xAxisData,
        axisLine: {
          lineStyle: {
            color: Color.echartItems.xAxisLine,
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          color: Color.echartItems.xAxisLabel,
          margin: 6, // 与横轴的距离
          fontSize: 12,
        },
      },
      // 横向滚动条
      dataZoom: [
        {
          show: displayRoom,
          bottom: 20,
          start: 0,
          end: displayRoom ? (maxBarNumber * 100) / this.props.data.length : 100,
          height: 40,
          left: 20,
          right: 20,
          handleColor: Color.echartItems.dataZoomHandBg, // 滑动图标的颜色
          borderColor: Color.echartItems.dataZoomBorderBg, // 边框颜色
          backgroundColor: Color.echartItems.dataZoomBg, // 滚动条未选中区域的背景颜色
          dataBackground: {
            lineStyle: {
              color: Color.echartItems.dataZoomShadowBg,
            },
            areaStyle: {
              color: Color.echartItems.dataZoomShadowBg, // 滚动条数据阴影区域的背景颜色
              shadowColor: Color.echartItems.dataZoomShadowBg, // 滚动条数据阴影区域的背景颜色
            },
          },
          fillerColor: Color.echartItems.dataZoomChoosedBg, // 滚动条选中区域的背景颜色
        },
      ],
      // 纵轴
      yAxis: {
        name: '', // 坐标轴显示名称
        type: 'value',
        nameTextStyle: {
          // Y轴名称文本样式
          color: Color.echartItems.title,
          fontSize: 12,
        },
        axisLine: {
          // Y轴轴线样式
          show: false,
          lineStyle: {
            color: Color.echartItems.yAxisLine,
          },
        },
        axisTick: {
          // Y轴间隔小线段样式
          show: false,
        },
        axisLabel: {
          // Y轴文本样式
          margin: 4, // 与纵轴的距离
          color: Color.echartItems.yAxisLabel,
          fontSize: 12,
        },
        splitNumber: 4, // 坐标轴的分割段数，需要注意的是这个分割段数只是个预估值，最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整
        splitLine: {
          // Y轴分割线样式
          show: true,
          lineStyle: {
            type: 'dashed',
            color: Color.echartItems.splitLine,
          },
        },
        scale: true,
        // 处理买入和卖出都有时，因卖出的markpoint比买入高，有时坐标会不在左侧坐标范围内，顾将坐标加高
        // 若数据中不包含markpoint数据，则正常展示
        max: markPointData && markPointData.length > 0 ? parseInt(max) + 1 + parseInt((max - min) / 5) : max,
        min,
      },
      series: [
        {
          name: '日K',
          type: 'candlestick',
          data: seriesData,
          itemStyle: {
            color: Color.debtAndProfit.text[0],
            color0: Color.debtAndProfit.text[1],
            borderColor: Color.debtAndProfit.text[0],
            borderColor0: Color.debtAndProfit.text[1],
          },
          markPoint: {
            data: markPointData,
          },
          barMaxWidth: 20, // K线图柱子最大宽度
        },
      ],
    };
  };

  // 将数据解析成组件需要的格式
  splitData = (rawData) => {
    const xAxisData = []; // 横轴
    const seriesData = []; // series数据
    const markPointData = []; // markpoint
    let max = 0; // 记录最大数值
    let min = -1; // 记录最小值

    rawData.forEach((item) => {
      xAxisData.push(item.time);
      seriesData.push([item.open, item.close, item.lowest, item.highest]);
      if (item.highest > max) max = item.highest;
      if (min == -1 || item.lowest < min) min = item.lowest;
      if (item.trading && item.trading.length > 0) {
        const buy = item.trading.filter((element) => element.type == '买');
        const sale = item.trading.filter((element) => element.type == '卖');
        if (sale && sale.length > 0) {
          markPointData.push({
            coord: [item.time, buy && buy.length > 0 ? item.highest * 1.01 : item.highest],
            value: '卖',
            itemStyle: {
              color: Color.debtAndProfit.text[1],
            },
          });
        }
        if (buy && buy.length > 0) {
          markPointData.push({
            coord: [item.time, item.highest],
            value: '买',
            itemStyle: {
              color: Color.debtAndProfit.text[0],
            },
          });
        }
      }
    });

    return {
      xAxisData,
      seriesData,
      markPointData,
      max,
      min,
    };
  };

  render() {
    const { height, width, data } = this.props;
    if (data != undefined && data != null) {
    }

    return (
      <div>
        <Spin spinning={data == undefined && data == null} tip='加载中...'>
          {data != undefined && data != null ? (
            data.length > 0 ? (
              <ReactEcharts
                option={this.getOption()}
                style={{ height, width }}
                // 是否不跟之前设置的 option 进行合并，默认为 false，即合并。
                notMerge={true}
              />
            ) : (
              <NoDataC />
            )
          ) : (
            <div style={{ height, width }}></div>
          )}
        </Spin>
      </div>
    );
  }
}

/*
备注：
  当yAxis和series值为null或undefined时，显示loading状态
  当yAxis和series值为空数组[]时，显示“暂无数据”
  当yAxis和series值为有值的数组时，正常实现图形
*/
CandlestickChartsC.propTypes = {
  data: PropTypes.array, // [{time:'', open:xxx, close:xxx, lowest:xxx, highest:xxx，trading:[{type:'买'，value:112.34},{type:'卖'，value:112.34}]},...]
  height: PropTypes.oneOfType([
    // 图表高度（百分比、数值、auto（设置auto，则会根据当前数据量的多少自动设置图形高度））
    PropTypes.string,
    PropTypes.number,
  ]),
  width: PropTypes.oneOfType([
    // 图表宽度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  toolTipFormat: PropTypes.func, // 提示框内容显示格式处理
  gridLeft: PropTypes.number, // 左轴距离左侧距离
  gridRight: PropTypes.number, // 右轴距离右侧距离
  maxBarNumber: PropTypes.number, // 设置一面展示多少数据
};

export default CandlestickChartsC;
